package drds.plus.sql_process.abstract_syntax_tree.node.query;

import drds.plus.sql_process.abstract_syntax_tree.ObjectCreateFactory;
import drds.plus.sql_process.abstract_syntax_tree.execute_plan.ExecutePlan;
import drds.plus.sql_process.abstract_syntax_tree.execute_plan.query.QueryWithIndex;
import drds.plus.sql_process.abstract_syntax_tree.expression.item.function.Filter;
import drds.plus.sql_process.abstract_syntax_tree.expression.order_by.OrderBy;
import drds.plus.sql_process.abstract_syntax_tree.node.Node;
import drds.plus.sql_process.abstract_syntax_tree.node.query.build.$Query$Builder;
import drds.plus.sql_process.abstract_syntax_tree.node.query.build.QueryBuilder;
import lombok.Getter;
import lombok.Setter;

import java.util.List;

/**
 * (query)
 * 对于一个单个逻辑表的query，处理node.
 */
public class $Query$ extends Query {
    @Setter
    @Getter
    private $Query$Builder $Query$Builder;

    public $Query$() {
        this(null);
    }

    public $Query$(Query query) {
        this(query, null);
    }

    public $Query$(Query query, Filter where) {
        super();
        this.$Query$Builder = new $Query$Builder(this);
        this.where = where;
        this.setFirstSubNodeQueryNode(query);
        if (query != null) {
            query.setSubQueryAndSetNeedBuild(true);// 默认设置为subQuery
        }
    }

    public Query getFirstSubNodeQueryNode() {
        if (this.getNodeList().isEmpty()) {
            return null;
        }
        return (Query) this.getNodeList().get(0);
    }

    public void setFirstSubNodeQueryNode(Query query) {
        if (query == null) {
            return;
        }
        if (this.getNodeList().isEmpty()) {
            this.getNodeList().add(query);
        } else {
            this.getNodeList().set(0, query);
        }
        setNeedBuild(true);
    }

    public List<Node> getNodeList() {
        if (super.getNodeList() != null && super.getNodeList().size() == 1) {
            if (super.getNodeList().get(0) == null) {
                super.getNodeList().remove(0);
            }
        }

        return super.getNodeList();
    }

    public void build() {
        if (this.isNeedBuild()) {
            this.$Query$Builder.build();
        }
        setNeedBuild(false);
    }

    public List getCompleteOrderByList() {
        List<OrderBy> orderByList = getOrderByListCombinedWithGroupByList();
        if (orderByList != null) {
            return orderByList;
        } else {
            return this.getFirstSubNodeQueryNode().getCompleteOrderByList();
        }
    }

    public QueryBuilder getQueryNodeBuilder() {
        return $Query$Builder;
    }

    public String getName() {
        return this.getAlias();
    }

    public ExecutePlan toExecutePlan(int shareIndex) {
        subQueryToExecutePlan(shareIndex);
        QueryWithIndex queryWithIndex = ObjectCreateFactory.createQueryWithIndex();
        queryWithIndex.setAlias(this.getAlias());
        queryWithIndex.setSelectItemList(this.getSelectItemList());
        queryWithIndex.setConsistent(this.isConsistent());
        queryWithIndex.setGroupByList(this.getGroupByList());
        queryWithIndex.setKeyFilter(this.getIndexQueryKeyFilter());
        queryWithIndex.setValueFilter(this.getResultFilter());
        queryWithIndex.setLimitFrom(this.getLimitFrom());
        queryWithIndex.setLimitTo(this.getLimitTo());
        queryWithIndex.setLockMode(this.getLockMode());
        queryWithIndex.setOrderByList(this.getOrderByList());
        // 不能传递shareIndex,代理对象会自处理
        queryWithIndex.setSubQuery((drds.plus.sql_process.abstract_syntax_tree.execute_plan.query.Query) this.getFirstSubNodeQueryNode().toExecutePlan());
        queryWithIndex.setSql(this.getSql());
        queryWithIndex.setIsSubQuery(this.isSubQuery());
        queryWithIndex.setExistAggregate(this.isExistAggregateExpression());
        queryWithIndex.setDataNodeId(this.getDataNodeId(shareIndex));
        queryWithIndex.setSubQueryFilterId(this.getSubQueryId());
        queryWithIndex.setSubQueryFilter(this.getSubQueryFunctionFilter());
        queryWithIndex.setExistSequenceValue(this.isExistSequenceValue());
        return queryWithIndex;
    }

    public $Query$ copy() {
        $Query$ $Query$ = new $Query$(this.getFirstSubNodeQueryNode().copy());
        this.copySelfTo($Query$);
        return $Query$;
    }

    public $Query$ copySelf() {
        $Query$ $Query$Node = new $Query$(this.getFirstSubNodeQueryNode());
        this.copySelfTo($Query$Node);
        return $Query$Node;
    }

    public $Query$ deepCopy() {
        $Query$ $Query$Node = new $Query$(this.getFirstSubNodeQueryNode().deepCopy());
        this.deepCopySelfTo($Query$Node);
        return $Query$Node;
    }


}
